export default class indexDb {
    #IDBRequest;
    #database;
    #databaseName;
    #databaseVersion;

    constructor(databaseName, databaseVersion) {
        this.#databaseName = databaseName;
        this.#databaseVersion = databaseVersion;
    }

    async createDatabase(tableNameArr) {
        return new Promise((resolve) => {
            const nameType = Object.prototype.toString.call(this.#databaseName);
            const versionType = Object.prototype.toString.call(this.#databaseVersion);
            if (nameType === '[object String]' && versionType === '[object Number]') {
                this.#IDBRequest = window.indexedDB.open(this.#databaseName, this.#databaseVersion);

                this.#IDBRequest.onerror = (event) => {
                    console.error("打开database出错", event);
                    resolve(event);
                };

                /* 打开事件在更新事件后 */
                this.#IDBRequest.onsuccess = (event) => {
                    console.log("打开database成功", event);
                    this.#database = this.#IDBRequest.result;
                    resolve(true);
                };

                this.#IDBRequest.onupgradeneeded = (event) => {
                    console.log("database有更新", event);
                    this.#database = event.target.result;

                    Array.isArray(tableNameArr) && tableNameArr.map(async (tableInfo) => {
                        await this.#createTable(tableInfo.tableName, tableInfo.keyPath);
                    });

                    Array.isArray(tableNameArr) && this.getTables().filter((tableName) => { return !tableNameArr.map((tableInfo) => { return tableInfo.tableName }).includes(tableName) }).map(async (tableName) => { await this.#deleteTable(tableName) });
                }
            } else {
                resolve(false);
            }
        });
    }

    async #createTable(tableName, keyPath = "id") {
        return new Promise((resolve) => {
            if (this.#database) {
                if (!this.#database.objectStoreNames.contains(tableName)) {
                    const tableObj = this.#database.createObjectStore(tableName, { autoIncrement: true, keyPath });
                    tableObj.transaction.oncomplete = () => {
                        resolve(true);
                    }
                } else {
                    resolve();
                }
            } else {
                resolve();
            }
        });
    }

    async #deleteTable(tableName) {
        return new Promise((resolve) => {
            if (this.#database) {
                if (this.#database.objectStoreNames.contains(tableName)) {
                    this.#database.deleteObjectStore(tableName);
                    resolve(true);
                } else {
                    resolve();
                }
            } else {
                resolve();
            }
        });
    }

    getTables() {
        return Array.from(this.#database.objectStoreNames);
    }

    async addData(tableName, data) {
        return new Promise((resolve) => {
            if (!this.#database.objectStoreNames.contains(tableName)) {
                console.error(`不存在${tableName}这张表`);
                resolve(false);
            }
            const execRes = this.#database.transaction([tableName], 'readwrite').objectStore(tableName).add(data);

            execRes.onsuccess = (event) => {
                resolve(true);
            };

            execRes.onerror = (event) => {
                console.error(`添加数据出错`, tableName, data);
                resolve(event);
            }
        });
    }

    async getDataById(tableName, id) {
        return new Promise((resolve) => {
            if (!this.#database.objectStoreNames.contains(tableName)) {
                console.error(`不存在${tableName}这张表`);
                resolve(false);
            }

            const execRes = this.#database.transaction([tableName]).objectStore(tableName).get(id);

            execRes.onsuccess = (event) => {
                resolve(execRes.result);
            };

            execRes.onerror = (event) => {
                onsole.error(`读取数据出错`, tableName, event);
                resolve(false);
            }
        });
    }

    async getAllData(tableName) {
        return new Promise((resolve) => {
            if (!this.#database.objectStoreNames.contains(tableName)) {
                console.error(`不存在${tableName}这张表`);
                resolve(false);
            }

            const execRes = this.#database.transaction([tableName]).objectStore(tableName);
            let res = [];

            execRes.openCursor().onsuccess = (event) => {
                const cursor = event.target.result;
                if (cursor) {
                    res.push({
                        id: cursor.key,
                        value: cursor.value
                    });
                    cursor.continue();
                } else {
                    console.log('没有更多数据了！');
                }
                resolve(res);
            };
        });
    }

    async update(tableName, data) {
        return new Promise((resolve) => {
            if (!this.#database.objectStoreNames.contains(tableName)) {
                console.error(`不存在${tableName}这张表`);
                resolve(false);
            }

            const execRes = this.#database.transaction([tableName], 'readwrite')
                .objectStore(tableName)
                .put(data);

            execRes.onsuccess = (event) => {
                console.log('数据更新成功');
                resolve(true);
            };

            execRes.onerror = (event) => {
                console.error('数据更新失败', event);
                resolve(false);
            }
        });
    }

    async deleteData(tableName, id) {
        return new Promise((resolve) => {
            if (!this.#database.objectStoreNames.contains(tableName)) {
                console.error(`不存在${tableName}这张表`);
                resolve(false);
            }

            const execRes = this.#database.transaction([tableName], 'readwrite')
                .objectStore(tableName)
                .delete(id);

            execRes.onsuccess = (event) => {
                console.log('数据删除成功');
                resolve(true);
            };
        });
    }
}